<?php

namespace app\common\library\util;
use malkusch\lock\mutex\FlockMutex;
use malkusch\lock\mutex\PredisMutex;
use Predis\Client;

class Mutex
{
    /**
     * 互斥锁的实现
     * @param \Closure $func 回调函数
     * @param string $keyName 当type的值为 redis:则为key名称，file：则为锁定的文件名称
     * @param string $type 类型
     * @param int $timeout 锁定超时时间
     * @return void
     * @throws \Exception
     */
    public static function lock(\Closure $func,string $keyName = 'redis-lock',string $type = 'predis',int $timeout = 10){
        $lock= null;
        if($type == 'predis'){
            $predis = new Client();
            $lock = new PredisMutex([$predis],$keyName,$timeout);
        }elseif($type == 'file'){
            $file = fopen($keyName,'r');
            $lock = new FlockMutex($file, $timeout);
        }

        if(!$lock){
            throw new \Exception('锁类型不支持：'.$type);
        }

        $lock->synchronized($func);
    }
}